﻿using System;
using System.IO;
using UtilZ.Dotnet.Ex.Base;

namespace UtilZ.Dotnet.Ex.Model
{
    /// <summary>
    /// 通信传输数据接口
    /// </summary>
    public interface ITransferData : IDisposableZ
    {
        /// <summary>
        /// 数据Tag
        /// </summary>
        object Tag { get; set; }

        /// <summary>
        /// 数据解析结果
        /// </summary>
        DataParseResult ParseResult { get; }

        /// <summary>
        /// 指示当前数据在发送拥堵时是否允许丢弃[true:允许丢弃;fasle:不允许丢弃]
        /// </summary>
        bool AllowDiscard { get; }


        /// <summary>
        /// 获取当前对象的数据buffer.
        /// 注:
        /// 当数据buffer中的数据类型(BufferData.DataType)为BufferDataType.File时,外数据使用完成后,需要外部删除文件;
        /// 当数据buffer中的数据类型(BufferData.DataType)为BufferDataType.Stream时,外数据使用完成后,需要外部对bufferData.Stream调用Dispose方法.
        /// </summary>
        /// <param name="options">选项,为null使用默认选项</param>
        /// <returns>数据buffer</returns>
        DataSource ToBufferData(TransferDataOptions options = null);

        /// <summary>
        /// 将当前对象写到指定的数据流中
        /// </summary>
        /// <param name="bufferData">目标数据</param>
        /// <param name="writer">当前对象要写入数据的BinaryWriter</param>
        void ToBufferData(DataSource bufferData, BinaryWriter writer);

        /// <summary>
        /// 将当前对象写到指定的数据流中
        /// </summary>
        /// <param name="bufferData">目标数据</param>
        void ToBufferData(ArraySpan<byte> bufferData);

        /// <summary>
        /// 将当前对象写到指定的数据流中
        /// </summary>
        /// <param name="bufferData">目标数据</param>
        /// <param name="writer">当前对象要写入数据的BinaryWriter</param>
        void ToBufferData(ArraySpan<byte> bufferData, BinaryWriter writer);

        /// <summary>
        /// 将当前对象写到指定的数据流中
        /// </summary>
        /// <param name="buffer">目标数据</param>
        /// <param name="statIndex">目标数据起始位置</param>
        /// <returns>写入数据长度</returns>
        int ToBytes(byte[] buffer, int statIndex);

        /// <summary>
        /// 将当前对象写到指定的数据流中
        /// </summary>
        /// <returns>目标数据</returns>
        byte[] ToBytes();


        /// <summary>
        /// 获取当前对象转换成字节数据长度
        /// </summary>
        /// <returns>当前对象转换成字节数据长度</returns>
        long GetBufferLength();





        /// <summary>
        /// 将数据解析到当前对象
        /// </summary>
        /// <param name="data">数据</param>
        void FromBufferData(DataSource data);

        /// <summary>
        /// 将数据buffer解析到当前对象
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="startIndex">数据起始位置</param>
        /// <param name="length">数据长度</param>
        void FromBufferData(byte[] data, int startIndex, int length);

        /// <summary>
        /// 将数据buffer解析到当前对象
        /// </summary>
        /// <param name="data">数据</param>
        void FromBufferData(byte[] data);



        /// <summary>
        /// 重置当前数据对象
        /// </summary>
        void Reset();

    }

}
